import type { AsyncDataResult, Dictionary } from '../define/types'
import type IAggregate from '../define/aggregate'
import knex from '../connection'

class Aggregate implements IAggregate {
  async _aggregateQuery(table: string, conditions: Dictionary, method: string, column?: string, groupBy?: string): AsyncDataResult {
    let query: any = knex(table).where(conditions)
    if (column) query = query[method](column)
    else query = query[method]()
    if (groupBy) query = query.groupBy(groupBy)
    return await query
  }

  async count(table: string, conditions: Dictionary = {}, groupBy?: string): AsyncDataResult {
    return this._aggregateQuery(table, conditions, 'count', undefined, groupBy)
  }

  async sum(table: string, column: string, conditions: Dictionary = {}, groupBy?: string): AsyncDataResult {
    return this._aggregateQuery(table, conditions, 'sum', column, groupBy)
  }

  async avg(table: string, column: string, conditions: Dictionary = {}, groupBy?: string): AsyncDataResult {
    return this._aggregateQuery(table, conditions, 'avg', column, groupBy)
  }

  async max(table: string, column: string, conditions: Dictionary = {}, groupBy?: string): AsyncDataResult {
    return this._aggregateQuery(table, conditions, 'max', column, groupBy)
  }

  async min(table: string, column: string, conditions: Dictionary = {}, groupBy?: string): AsyncDataResult {
    return this._aggregateQuery(table, conditions, 'min', column, groupBy)
  }
}

export default new Aggregate()